<?php
/**
 * 完善的用户API
 * 包含微信登录、用户资料管理、头像上传等功能
 */

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');

if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    exit;
}

// 数据库配置
$dbConfig = [
    'host' => 'localhost',
    'name' => 'nzy_congqian_cn', 
    'user' => 'nzy_congqian_cn',
    'pass' => 'FsnXrDfDhm4wFJSX',
    'charset' => 'utf8mb4'
];

// 微信小程序配置
$wxConfig = [
    'appid' => 'wxf7a6dfca45112e43',
    'secret' => '36895ffe99019fd5498f4e3bf400f0a0'
];

// 数据库连接
try {
    $dsn = "mysql:host={$dbConfig['host']};dbname={$dbConfig['name']};charset={$dbConfig['charset']}";
    $pdo = new PDO($dsn, $dbConfig['user'], $dbConfig['pass']);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    jsonResponse([
        'success' => false,
        'message' => '数据库连接失败: ' . $e->getMessage()
    ]);
}

// 响应函数
function jsonResponse($data) {
    echo json_encode($data, JSON_UNESCAPED_UNICODE);
    exit;
}

function success($data = null, $message = '操作成功') {
    jsonResponse([
        'code' => 200,
        'success' => true,
        'message' => $message,
        'data' => $data,
        'timestamp' => time()
    ]);
}

function error($message = '操作失败', $code = 400) {
    jsonResponse([
        'code' => $code,
        'success' => false,
        'message' => $message,
        'data' => null,
        'timestamp' => time()
    ]);
}

// 获取微信用户信息
function getWxUserInfo($code) {
    global $wxConfig;
    
    $url = "https://api.weixin.qq.com/sns/jscode2session";
    $params = [
        'appid' => $wxConfig['appid'],
        'secret' => $wxConfig['secret'],
        'js_code' => $code,
        'grant_type' => 'authorization_code'
    ];
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url . '?' . http_build_query($params));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    
    $response = curl_exec($ch);
    
    if (curl_error($ch)) {
        return ['errcode' => -1, 'errmsg' => 'Network error: ' . curl_error($ch)];
    }
    
    curl_close($ch);
    return json_decode($response, true);
}

// 生成token
function generateToken($openid) {
    return md5($openid . time() . rand(1000, 9999));
}

// 验证token
function verifyToken($token) {
    global $pdo;
    
    if (empty($token)) {
        return false;
    }
    
    // 移除Bearer前缀
    if (strpos($token, 'Bearer ') === 0) {
        $token = substr($token, 7);
    }
    
    try {
        $sql = "SELECT * FROM users WHERE token = ? AND token_expires > NOW() AND status = 'active'";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$token]);
        return $stmt->fetch(PDO::FETCH_ASSOC);
    } catch (Exception $e) {
        return false;
    }
}

// 获取当前用户
function getCurrentUser() {
    $token = getAuthToken();
    if (!$token) {
        error('需要登录', 401);
    }
    
    $user = verifyToken($token);
    if (!$user) {
        error('登录已过期，请重新登录', 401);
    }
    
    return $user;
}

// 获取认证token
function getAuthToken() {
    $headers = getallheaders();
    $authHeader = $headers['Authorization'] ?? $headers['authorization'] ?? '';
    
    if (strpos($authHeader, 'Bearer ') === 0) {
        return substr($authHeader, 7);
    }
    
    return $_GET['token'] ?? $_POST['token'] ?? '';
}

// 记录登录日志
function logUserLogin($userId, $loginType = 'wechat') {
    global $pdo;
    
    try {
        $sql = "INSERT INTO user_login_logs (user_id, login_type, login_ip, user_agent, platform, login_at) 
                VALUES (?, ?, ?, ?, 'miniprogram', NOW())";
        
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
            $userId,
            $loginType,
            $_SERVER['REMOTE_ADDR'] ?? 'unknown',
            $_SERVER['HTTP_USER_AGENT'] ?? ''
        ]);
    } catch (Exception $e) {
        // 日志记录失败不影响主要功能
        error_log("Login log failed: " . $e->getMessage());
    }
}

// 记录资料变更日志
function logProfileChange($userId, $fieldName, $oldValue, $newValue, $reason = '') {
    global $pdo;
    
    try {
        $sql = "INSERT INTO user_profile_logs (user_id, field_name, old_value, new_value, change_reason, changed_ip) 
                VALUES (?, ?, ?, ?, ?, ?)";
        
        $stmt = $pdo->prepare($sql);
        $stmt->execute([
            $userId,
            $fieldName,
            $oldValue,
            $newValue,
            $reason,
            $_SERVER['REMOTE_ADDR'] ?? 'unknown'
        ]);
    } catch (Exception $e) {
        error_log("Profile change log failed: " . $e->getMessage());
    }
}

// 上传头像
function uploadAvatar() {
    $user = getCurrentUser();
    
    if (!isset($_FILES['avatar'])) {
        error('未选择文件');
    }
    
    $file = $_FILES['avatar'];
    
    // 验证文件
    $allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'];
    $maxSize = 2 * 1024 * 1024; // 2MB
    
    if ($file['error'] !== UPLOAD_ERR_OK) {
        error('文件上传失败');
    }
    
    if (!in_array($file['type'], $allowedTypes)) {
        error('只支持 JPG、PNG、GIF 格式的图片');
    }
    
    if ($file['size'] > $maxSize) {
        error('文件大小不能超过 2MB');
    }
    
    // 验证图片有效性
    $imageInfo = getimagesize($file['tmp_name']);
    if (!$imageInfo) {
        error('无效的图片文件');
    }
    
    // 生成文件名
    $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
    $filename = 'avatar_' . $user['id'] . '_' . time() . '.' . $extension;
    
    // 使用相对于网站根目录的上传目录
    $uploadDir = $_SERVER['DOCUMENT_ROOT'] . '/uploads/avatars/';
    $webPath = '/uploads/avatars/' . $filename;
    
    // 创建上传目录
    if (!file_exists($uploadDir)) {
        if (!mkdir($uploadDir, 0755, true)) {
            error('无法创建上传目录');
        }
    }
    
    $uploadPath = $uploadDir . $filename;
    
    // 移动文件
    if (!move_uploaded_file($file['tmp_name'], $uploadPath)) {
        error('文件保存失败');
    }
    
    // 更新数据库
    try {
        global $pdo;
        
        // 获取旧头像
        $oldAvatar = $user['avatar'];
        
        // 更新新头像
        $sql = "UPDATE users SET avatar = ?, updated_at = NOW() WHERE id = ?";
        $stmt = $pdo->prepare($sql);
        $stmt->execute([$webPath, $user['id']]);
        
        // 记录变更日志
        logProfileChange($user['id'], 'avatar', $oldAvatar, $webPath, '用户上传头像');
        
        // 删除旧头像文件（如果存在且不是默认头像）
        if ($oldAvatar && strpos($oldAvatar, '/uploads/avatars/') === 0) {
            $oldFilePath = $_SERVER['DOCUMENT_ROOT'] . $oldAvatar;
            if (file_exists($oldFilePath)) {
                @unlink($oldFilePath);
            }
        }
        
        success([
            'avatar_url' => $webPath,
            'full_url' => 'https://' . $_SERVER['HTTP_HOST'] . $webPath
        ], '头像上传成功');
        
    } catch (Exception $e) {
        // 如果数据库更新失败，删除已上传的文件
        if (file_exists($uploadPath)) {
            @unlink($uploadPath);
        }
        error('头像保存失败: ' . $e->getMessage());
    }
}

// 获取请求数据
function getRequestData() {
    $input = file_get_contents('php://input');
    if (!empty($input)) {
        return json_decode($input, true) ?: [];
    }
    return $_POST;
}

// 处理请求
$method = $_SERVER['REQUEST_METHOD'];
$action = $_GET['action'] ?? '';

try {
    switch ($method) {
        case 'POST':
            switch ($action) {
                case 'login':
                    // 微信登录
                    $input = getRequestData();
                    
                    if (empty($input['code'])) {
                        error('缺少授权码');
                    }
                    
                    // 获取微信用户信息
                    $wxInfo = getWxUserInfo($input['code']);
                    
                    if (isset($wxInfo['errcode'])) {
                        error('微信登录失败: ' . ($wxInfo['errmsg'] ?? '未知错误'));
                    }
                    
                    $openid = $wxInfo['openid'];
                    $sessionKey = $wxInfo['session_key'];
                    $unionid = $wxInfo['unionid'] ?? null;
                    
                    // 检查用户是否已存在
                    $sql = "SELECT * FROM users WHERE openid = ?";
                    $stmt = $pdo->prepare($sql);
                    $stmt->execute([$openid]);
                    $user = $stmt->fetch(PDO::FETCH_ASSOC);
                    
                    if (!$user) {
                        // 创建新用户
                        $token = generateToken($openid);
                        $sql = "INSERT INTO users (openid, unionid, session_key, token, token_expires, 
                                last_login_at, last_login_ip, login_count, status, created_at) 
                                VALUES (?, ?, ?, ?, DATE_ADD(NOW(), INTERVAL 7 DAY), NOW(), ?, 1, 'active', NOW())";
                        
                        $stmt = $pdo->prepare($sql);
                        $stmt->execute([$openid, $unionid, $sessionKey, $token, $_SERVER['REMOTE_ADDR'] ?? 'unknown']);
                        $userId = $pdo->lastInsertId();
                        
                        $user = [
                            'id' => $userId,
                            'openid' => $openid,
                            'token' => $token,
                            'nickname' => null,
                            'avatar' => null,
                            'phone' => null,
                            'gender' => 0,
                            'city' => null,
                            'province' => null,
                            'country' => null
                        ];
                    } else {
                        // 更新现有用户
                        $token = generateToken($openid);
                        $sql = "UPDATE users SET session_key = ?, unionid = ?, token = ?, 
                                token_expires = DATE_ADD(NOW(), INTERVAL 7 DAY), 
                                last_login_at = NOW(), last_login_ip = ?, 
                                login_count = login_count + 1, updated_at = NOW() 
                                WHERE id = ?";
                        
                        $stmt = $pdo->prepare($sql);
                        $stmt->execute([
                            $sessionKey, 
                            $unionid, 
                            $token, 
                            $_SERVER['REMOTE_ADDR'] ?? 'unknown', 
                            $user['id']
                        ]);
                        $user['token'] = $token;
                    }
                    
                    // 记录登录日志
                    logUserLogin($user['id']);
                    
                    success([
                        'token' => $user['token'],
                        'userInfo' => [
                            'id' => $user['id'],
                            'nickname' => $user['nickname'],
                            'avatar' => $user['avatar'],
                            'phone' => $user['phone'],
                            'gender' => intval($user['gender']),
                            'city' => $user['city'],
                            'province' => $user['province'],
                            'country' => $user['country']
                        ]
                    ], '登录成功');
                    break;
                    
                case 'upload-avatar':
                    // 上传头像
                    uploadAvatar();
                    break;
                    
                case 'refresh-token':
                    // 刷新token
                    $user = getCurrentUser();
                    
                    $newToken = generateToken($user['openid']);
                    $sql = "UPDATE users SET token = ?, token_expires = DATE_ADD(NOW(), INTERVAL 7 DAY) 
                            WHERE id = ?";
                    
                    $stmt = $pdo->prepare($sql);
                    $stmt->execute([$newToken, $user['id']]);
                    
                    success(['token' => $newToken], 'Token刷新成功');
                    break;
                    
                default:
                    error('无效的操作');
            }
            break;
            
        case 'GET':
            switch ($action) {
                case 'profile':
                    // 获取用户资料
                    $user = getCurrentUser();
                    
                    success([
                        'id' => $user['id'],
                        'openid' => $user['openid'],
                        'nickname' => $user['nickname'],
                        'avatar' => $user['avatar'],
                        'gender' => intval($user['gender']),
                        'city' => $user['city'],
                        'province' => $user['province'],
                        'country' => $user['country'],
                        'language' => $user['language'],
                        'phone' => $user['phone'],
                        'email' => $user['email'],
                        'real_name' => $user['real_name'],
                        'birth_date' => $user['birth_date'],
                        'occupation' => $user['occupation'],
                        'education' => $user['education'],
                        'interests' => $user['interests'] ? json_decode($user['interests'], true) : [],
                        'last_login_at' => $user['last_login_at'],
                        'login_count' => intval($user['login_count']),
                        'created_at' => $user['created_at']
                    ]);
                    break;
                    
                case 'login-history':
                    // 获取登录历史
                    $user = getCurrentUser();
                    $page = max(1, intval($_GET['page'] ?? 1));
                    $limit = min(50, max(1, intval($_GET['limit'] ?? 10)));
                    $offset = ($page - 1) * $limit;
                    
                    $sql = "SELECT login_type, login_ip, user_agent, platform, login_at 
                            FROM user_login_logs 
                            WHERE user_id = ? 
                            ORDER BY login_at DESC 
                            LIMIT $limit OFFSET $offset";
                    
                    $stmt = $pdo->prepare($sql);
                    $stmt->execute([$user['id']]);
                    $logs = $stmt->fetchAll(PDO::FETCH_ASSOC);
                    
                    // 获取总数
                    $countSql = "SELECT COUNT(*) as total FROM user_login_logs WHERE user_id = ?";
                    $countStmt = $pdo->prepare($countSql);
                    $countStmt->execute([$user['id']]);
                    $total = $countStmt->fetch(PDO::FETCH_ASSOC)['total'];
                    
                    success([
                        'list' => $logs,
                        'pagination' => [
                            'page' => $page,
                            'limit' => $limit,
                            'total' => intval($total),
                            'pages' => ceil($total / $limit)
                        ]
                    ]);
                    break;
                    
                default:
                    error('无效的操作');
            }
            break;
            
        case 'PUT':
            switch ($action) {
                case 'profile':
                    // 更新用户资料
                    $user = getCurrentUser();
                    $input = getRequestData();
                    
                    // 允许更新的字段
                    $allowedFields = [
                        'nickname', 'avatar', 'gender', 'city', 'province', 'country', 
                        'language', 'phone', 'email', 'real_name', 'birth_date', 
                        'occupation', 'education', 'interests'
                    ];
                    
                    $updateData = [];
                    $params = [];
                    $changes = [];
                    
                    foreach ($allowedFields as $field) {
                        if (isset($input[$field]) && $input[$field] !== $user[$field]) {
                            $oldValue = $user[$field];
                            $newValue = $input[$field];
                            
                            // 特殊处理
                            if ($field === 'interests' && is_array($newValue)) {
                                $newValue = json_encode($newValue);
                            }
                            
                            $updateData[] = "$field = ?";
                            $params[] = $newValue;
                            $changes[] = ['field' => $field, 'old' => $oldValue, 'new' => $newValue];
                        }
                    }
                    
                    if (empty($updateData)) {
                        error('没有需要更新的数据');
                    }
                    
                    // 验证手机号格式
                    if (isset($input['phone']) && !empty($input['phone'])) {
                        if (!preg_match('/^1[3-9]\d{9}$/', $input['phone'])) {
                            error('手机号格式不正确');
                        }
                        
                        // 检查手机号是否已被其他用户使用
                        $checkSql = "SELECT id FROM users WHERE phone = ? AND id != ?";
                        $checkStmt = $pdo->prepare($checkSql);
                        $checkStmt->execute([$input['phone'], $user['id']]);
                        if ($checkStmt->fetch()) {
                            error('该手机号已被其他用户使用');
                        }
                    }
                    
                    // 验证邮箱格式
                    if (isset($input['email']) && !empty($input['email'])) {
                        if (!filter_var($input['email'], FILTER_VALIDATE_EMAIL)) {
                            error('邮箱格式不正确');
                        }
                    }
                    
                    // 验证性别
                    if (isset($input['gender']) && !in_array($input['gender'], [0, 1, 2])) {
                        error('性别参数无效');
                    }
                    
                    $params[] = $user['id'];
                    $sql = "UPDATE users SET " . implode(', ', $updateData) . 
                           ", updated_at = NOW() WHERE id = ?";
                    
                    $stmt = $pdo->prepare($sql);
                    $stmt->execute($params);
                    
                    // 记录变更日志
                    foreach ($changes as $change) {
                        logProfileChange($user['id'], $change['field'], $change['old'], $change['new'], '用户主动更新');
                    }
                    
                    success(null, '资料更新成功');
                    break;
                    
                default:
                    error('无效的操作');
            }
            break;
            
        default:
            error('不支持的请求方法');
    }
    
} catch (PDOException $e) {
    error('数据库错误: ' . $e->getMessage(), 500);
} catch (Exception $e) {
    error('服务器错误: ' . $e->getMessage(), 500);
}
?>